From 5d17bd4e992a6dabacb2fd55b57ec1eb51703800 Mon Sep 17 00:00:00 2001 From: robertl Date: Wed, 19 Nov 2008 02:52:35 +0000 Subject: [PATCH] Andreas Grimme contributes support for the XAiOX iTrackU GPS logger. --- Makefile.in | 2 +- itracku.c | 834 ++++++++++++++++++++++ reference/itracku.dat | Bin 0 -> 9568 bytes reference/itracku.unicsv | 599 ++++++++++++++++ testo | 9 + vecs.c | 15 + xmldoc/formats/itracku-bin.xml | 5 + xmldoc/formats/itracku.xml | 10 + xmldoc/formats/options/itracku-backup.xml | 10 + xmldoc/formats/options/itracku-new.xml | 12 + 10 files changed, 1495 insertions(+), 1 deletion(-) create mode 100644 itracku.c create mode 100644 reference/itracku.dat create mode 100644 reference/itracku.unicsv create mode 100644 xmldoc/formats/itracku-bin.xml create mode 100644 xmldoc/formats/itracku.xml create mode 100644 xmldoc/formats/options/itracku-backup.xml create mode 100644 xmldoc/formats/options/itracku-new.xml diff --git a/Makefile.in b/Makefile.in index d5347802b..b20154649 100644 --- a/Makefile.in +++ b/Makefile.in @@ -61,7 +61,7 @@ ALL_FMTS=$(MINIMAL_FMTS) gtm.o gpsutil.o pcx.o cetus.o copilot.o \ ggv_log.o g7towin.o garmin_gpi.o lmx.o random.o xol.o dg-100.o \ navilink.o mtk_logger.o ik3d.o osm.o destinator.o exif.o vidaone.o \ igo8.o gopal.o humminbird.o mapasia.o gnav_trl.o navitel.o ggv_ovl.o \ - jtr.o sbp.o mmo.o skyforce.o + jtr.o sbp.o mmo.o skyforce.o itracku.o FMTS=@FMTS@ diff --git a/itracku.c b/itracku.c new file mode 100644 index 000000000..493dfeab4 --- /dev/null +++ b/itracku.c @@ -0,0 +1,834 @@ +/* + Copyright (C) 2008 Andreas Grimme, andreas.grimme(at)gmx.net + Copyright (C) 2005 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ +/* + This module will download track data from a + + XAiOX iTrackU BLUETOOTH GPS-RECEIVER SiRF III + http://www.xaiox.com/itracku_sirf3.htm + + Example usage:: + + # Read from USB port, output trackpoints & waypoints in GPX format + ./gpsbabel -i itracku -f com14 -o gpx -F out.gpx + + */ +#include "defs.h" +#include +#include +#include "gbser.h" + +#define MYNAME "itracku" + +/* memory layout of the iTrackU data record */ +typedef struct { + gbuint8 longitude[4]; + gbuint8 latitude[4]; + gbuint8 creation_time[4]; + gbuint8 altitude[2]; + gbuint8 speed; + gbuint8 flag; +} itracku_data_record; + +static int itracku_is_valid_data_record(itracku_data_record* d); +static void to_itracku_data_record(const waypoint* wp, itracku_data_record* d); +static waypoint* to_waypoint(itracku_data_record* d); + +/* itracku file access */ +static void itracku_file_read_data_record(gbfile* fin, itracku_data_record* d); +static gbuint32 itracku_file_read_last_time(gbfile* fin); +static void itracku_file_read_waypts(gbfile* fin, void (*waypt_add)(waypoint *wpt)); +static void itracku_file_write_waypt(gbfile* fout, const waypoint *wpt); + +/* itracku device access */ +static const char read_update_data_command[] = { 0x60, 0xb5, 0, 0, 0, 0, 0 }; /* command string to start memory dump */ +static const int timeout = 1000; /* timeout for all read operations */ +static const char update_end_marker[] = "WP Update Over"; /* end marker for the memory dump */ +static const int update_end_marker_size = sizeof(update_end_marker); +#if LATER +static const int port_auto_detect_max_port = 32; +/* Special port name for auto detect. If used, gpsbabel will try to detect the serial +port with the itracku device automatically. */ +static const char port_auto_detect_filename[] = "auto:"; +#endif + +static int update_data_buffer_read_count = 0; +static char update_data_buffer[1024]; +static char* update_data_buffer_read; +static char* update_data_buffer_write; +static char* update_data_buffer_end; + +static void itracku_device_dump_waypts(void* fd, void (*waypt_add)(waypoint *wpt)); +static int itracku_device_update_data_init(); +static int itracku_device_update_data_read(void* buf, int len); +static void itracku_device_write_string(const char* s); +static const char* itracku_device_read_string(); + +/* global variables */ +static void *fd; /* serial fd */ +static gbfile* fin; /* input file handle */ +static gbfile* fout; /* output file handle */ +static gbfile* fbackup; /* backup file handle */ +static gbuint32 backup_last_creation_time; /* time of last data record in backup file */ +static gbuint32 new_waypoint_count; /* count of new waypoints */ +static char *port; /* serial port name */ +static char *backup_file_name; /* "backup" command option */ +static char *only_new; /* "new" command option */ + +static void +dbg(int l, const char *msg, ...) +{ + va_list ap; + va_start(ap, msg); + if (global_opts.debug_level >= l) { + fprintf(stderr, MYNAME ": "); + vfprintf(stderr,msg, ap); + fprintf(stderr, "\n"); + fflush(stderr); + } + va_end(ap); +} + +static void +itracku_device_write_string(const char* s) +{ + int size = strlen(s) + 1; + dbg(1, "write to device: %s", s); + gbser_write(fd, s, size); +} + +static const char* +itracku_device_read_string() +{ + const int size = 1024; + char* s = xmalloc(size); + gbser_read_line(fd, s, size, 1000, 0, 0); + dbg(1, "read from device: %s", s); + return s; +} + +static int +itracku_device_update_data_init() +{ + update_data_buffer_read = update_data_buffer; + update_data_buffer_write = update_data_buffer; + update_data_buffer_end = update_data_buffer + sizeof(update_data_buffer); + update_data_buffer_read_count = 0; + dbg(1, "start memory dump"); + return 0; +} + +static int +itracku_device_update_data_read(void* buf, int len) +{ + int rc; + + if (update_data_buffer_write - update_data_buffer_read >= len) { + memcpy(buf, update_data_buffer_read, len); + update_data_buffer_read += len; + return len; + } + + if (update_data_buffer_read + update_end_marker_size > update_data_buffer_end) { + memcpy(update_data_buffer, update_data_buffer_read, update_data_buffer_write - update_data_buffer_read); + update_data_buffer_write = update_data_buffer + (update_data_buffer_write - update_data_buffer_read); + update_data_buffer_read = update_data_buffer; + } + + rc = gbser_read_wait(fd, update_data_buffer_write, update_data_buffer_end - update_data_buffer_write, timeout); + if (rc == gbser_ERROR) { + return 0; + } + + update_data_buffer_write += rc; + update_data_buffer_read_count += rc; + dbg(1, "%5d kbyte read", update_data_buffer_read_count / 1024); + + if (0 == strncmp(update_end_marker, update_data_buffer_write - update_end_marker_size, update_end_marker_size - 1)) { + dbg(1, "end memory dump"); + return 0; + } + + return itracku_device_update_data_read(buf, len); +} + +/* + Convert the degrees format of itracku to double. + + itracku stores degrees in a + 32-bit unsigned integer. The lower + 6 digits in 10-base notation denote the + minutes multiplied by 10000, and digits + 7-9 denote the degrees. + + To express a negative number 0x80000000 is added + to integer. + + Example: the integer 49347687 is interpreted + as + + ddmmmmmm + 49347687 + + d=49 + m=34.7687 + + 49 degrees 34.7687 minutes +*/ +double +deg_min_to_deg(gbuint32 x) +{ + double sign; + gbuint32 sep; + gbuint32 d; + gbuint32 m10000; + + // determine the sign + if (x > 0x80000000) { + sign = -1.0; + x -= 0x80000000; + } + else { + sign = 1.0; + } + + sep = 1000000; + + // extract degrees + d = x / sep; + + // extract (minutes * 10000) + m10000 = x - d * sep; + + // convert minutes and degrees to a double + return sign * ((double)d + ((double)m10000) / 600000.0); +} + +/* + Convert degrees to the degrees format of itracku. +*/ +gbuint32 +deg_to_deg_min(double x) +{ + gbint32 sign; + double d; + double f; + + // determine sign + if (x >= 0) { + sign = 1; + } + else { + sign = -1; + x = -x; + } + + // integer degrees + d = floor(x); + + // fractional part + f = x - d; + + return + (gbuint32)d * 1000000 + // multiply integer degrees to shift it to the right digits. + (gbuint32)(f * 600000.0) + // multiply fractional part to convert to minutes and to to shift it to the right digits. + ((sign > 0) ? 0 : 0x80000000); // add 0x80000000 for negative degrees +} + +/* + Convert the itracku time format to time_t. +*/ +static time_t +decode_itracku_time(gbuint32 date) +{ + struct tm t; + t.tm_sec = date & 63; + t.tm_min = (date >> 6) & 63; + t.tm_hour = (date >> 12) & 31; + t.tm_mday = (date >> 17) & 31; + t.tm_mon = ((date >> 22) & 15) - 1; + t.tm_year = ((date >> 26) & 63) + 100; + return mkgmtime(&t); +} + +/* + Convert time_t to the itracku time format. +*/ +static gbuint32 +encode_itracku_time(time_t time) +{ + struct tm* t = gmtime(&time); + return + (t->tm_sec) + + (t->tm_min << 6) + + (t->tm_hour << 12) + + (t->tm_mday << 17) + + ((t->tm_mon + 1) << 22) + + ((t->tm_year - 100) << 26); +} + +/* + Converts a itracku waypoint record to a gpsbabel waypoint. +*/ +static waypoint* +to_waypoint(itracku_data_record* d) +{ + waypoint* wp; + wp = waypt_new(); + wp->longitude = deg_min_to_deg(le_read32(d->longitude)); + wp->latitude = deg_min_to_deg(le_read32(d->latitude)); + wp->creation_time = decode_itracku_time(le_read32(d->creation_time)); + wp->speed = KNOTS_TO_MPS((float)d->speed); + wp->wpt_flags.speed = 1; + wp->altitude = le_read16(d->altitude); + return wp; +} + +static void +to_itracku_data_record(const waypoint* wp, itracku_data_record* d) +{ + le_write32(d->longitude, deg_to_deg_min(wp->longitude)); + le_write32(d->latitude, deg_to_deg_min(wp->latitude)); + le_write32(d->creation_time, encode_itracku_time(wp->creation_time)); + d->speed = MPS_TO_KNOTS(wp->speed); + le_write16(d->altitude, wp->altitude); + d->flag = 0xff; +} + +/* + Tries to initialize an itracku device attached to + serial port fd. fd must already be opened. + + Returns gbser_OK if the initialization is sucessful, a + non-zero integer otherwise. +*/ +int +init_device() +{ + int rc; + const char* greeting; + // verify that we have a MTK based logger... + dbg(1, "verifying device on port %s", port); + + itracku_device_write_string("WP AP-Exit"); + gbser_flush(fd); + itracku_device_write_string("W'P Camera Detect"); + greeting = itracku_device_read_string(); + + if (0 == strcmp(greeting , "WP GPS+BT")) { + dbg(1, "device recognised on port %s", port); + rc = gbser_OK; + } + else { + dbg(1, "device not recognised on port %s", port); + rc = gbser_ERROR; + } + xfree((void*)greeting); + return rc; +} + +// Any arg in this list will appear in command line help and will be +// populated for you. +// Values for ARGTYPE_xxx can be found in defs.h and are used to +// select the type of option. +static +arglist_t itracku_args[] = { + { "backup", &backup_file_name, "Appends the input to a backup file", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + { "new", &only_new, "Only waypoints that are not the backup file", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, +// "default", ARGYTPE_STRING, ARG_NOMINMAX} , + ARG_TERMINATOR +}; + +/******************************************************************************* +* %%% global callbacks called by gpsbabel main process %%% * +*******************************************************************************/ + +static void +itracku_rd_init_common(const char *fname) +{ + new_waypoint_count = 0; + + if (backup_file_name != NULL) + { + fbackup = gbfopen(backup_file_name, "a+", MYNAME); + backup_last_creation_time = itracku_file_read_last_time(fbackup); + gbfseek(fbackup, 0, SEEK_END); + } + else + { + fbackup = NULL; + backup_last_creation_time = 0; + } + } + +static void +itracku_rd_ser_init(const char *fname) +{ +#if LATER + int i; + if (0 == strcmp(fname, port_auto_detect_filename)) { + dbg(1, "auto detecting port for iTrackU device"); + for (i=1; !fd && icreation_time) > backup_last_creation_time) { + backup_last_creation_time = le_read32(d->creation_time); + gbfwrite(d, sizeof(*d), 1, fbackup); + result = -1; + } + else { + result = (only_new == NULL); + } + } + else { + result = -1; + } + } + if (result) { + ++new_waypoint_count; + } + return result; +} + +static int +itracku_is_valid_data_record(itracku_data_record* d) +{ + return !(le_read32(d->longitude) == -1); +} + +static void +itracku_device_dump_waypts(void* fd, void (*waypt_add)(waypoint *wpt)) +{ + itracku_data_record d; + + dbg(1, "reading memory"); + gbser_write(fd, read_update_data_command, sizeof(read_update_data_command)); + + itracku_device_update_data_init(); + + while (itracku_device_update_data_read(&d, sizeof(d))) + { + if (itracku_is_valid_data_record(&d)) { + if (import_data_record(&d)) { + waypt_add(to_waypoint(&d)); + } + } + } +} + +static void +itracku_file_read_data_record(gbfile* fin, itracku_data_record* d) +{ + gbfread(d, sizeof(*d), 1, fin); +} + +static gbuint32 +itracku_file_read_last_time(gbfile* fin) +{ + itracku_data_record d; + gbsize_t s; + s = sizeof(itracku_data_record); + gbfseek(fin, 0, SEEK_END); + if (gbftell(fin) < s) + { + return 0; + } + gbfseek(fin, -(int)s, SEEK_END); + itracku_file_read_data_record(fin, &d); + return (gbuint32) le_read32(d.creation_time); +} + +static void +itracku_file_read_waypts(gbfile* fin, void (*waypt_add)(waypoint *wpt)) +{ + itracku_data_record d; + + while (gbfread(&d, sizeof(d), 1, fin)) + { + if (le_read32(d.longitude) == -1) { + continue; + } + if (import_data_record(&d)) { + waypt_add(to_waypoint(&d)); + } + } +} + +static void +itracku_file_write_waypt(gbfile* fout, const waypoint *wpt) +{ + itracku_data_record d; + to_itracku_data_record(wpt, &d); + gbfwrite(&d, sizeof(d), 1, fout); +} + +static void +itracku_waypt_input(void (*waypt_add)(waypoint *wpt)) +{ + if (fd) + { + itracku_device_dump_waypts(fd, waypt_add); + } + else + { + itracku_file_read_waypts(fin, waypt_add); + } +} + +static void +itracku_read_waypt(void) +{ + itracku_waypt_input(&waypt_add); +} + +static route_head* itracku_read_trk_track; + +static void +itracku_read_trk_waypt_add(waypoint *wpt) +{ + track_add_wpt(itracku_read_trk_track, wpt); +} + +static void +itracku_read_trk(void) +{ + itracku_read_trk_track = route_head_alloc(); + track_add_head(itracku_read_trk_track); + itracku_waypt_input(&itracku_read_trk_waypt_add); +} + +static void +itracku_read(void) +{ + switch(global_opts.objective) { + case wptdata: + itracku_read_waypt(); + break; + case trkdata: + itracku_read_trk(); + break; + case rtedata: + fatal(MYNAME ": reading routes is not supported.\n"); + break; + case posndata: + break; + } +} + +static void +itracku_wr_init(const char *fname) +{ + fout = gbfopen(fname, "w", MYNAME); +} + +static void +itracku_wr_deinit(void) +{ + gbfclose(fout); +} + +static void +itracku_output_waypoint(const waypoint * wp) +{ + itracku_file_write_waypt(fout, wp); +} + +static void +itracku_write(void) +{ + waypt_disp_all(itracku_output_waypoint); +} + +static void +itracku_exit(void) /* optional */ +{ +} + +static void +itracku_rt_init(const char *fname) +{ + itracku_rd_ser_init(fname); + itracku_device_write_string("WP AP-Exit"); +} + +static void +nmea_set_waypoint_time(waypoint *wpt, struct tm *time, int microseconds) +{ + if (time->tm_year == 0) + { + wpt->creation_time = ((((time_t)time->tm_hour * 60) + time->tm_min) * 60) + time->tm_sec; + wpt->microseconds = microseconds; + if (wpt->wpt_flags.fmt_use == 0) + { + wpt->wpt_flags.fmt_use = 1; + } + } + else + { + wpt->creation_time = mkgmtime(time); + wpt->microseconds = microseconds; + if (wpt->wpt_flags.fmt_use != 0) + { + wpt->wpt_flags.fmt_use = 0; + } + } +} + +static waypoint * +gprmc_parse(char *ibuf) +{ + double latdeg, lngdeg; + char lngdir, latdir; + double hms; + char fix; + unsigned int dmy; + double speed,course; + waypoint *waypt; + double microseconds; + struct tm tm; + + int rc = sscanf(ibuf,"$GPRMC,%lf,%c,%lf,%c,%lf,%c,%lf,%lf,%u", + &hms, &fix, &latdeg, &latdir, + &lngdeg, &lngdir, + &speed, &course, &dmy); + + if (rc == 0) + { + return NULL; + } + + microseconds = MILLI_TO_MICRO(1000 * (hms - (int)hms)); + + tm.tm_sec = (long) hms % 100; + hms = hms / 100; + tm.tm_min = (long) hms % 100; + hms = hms / 100; + tm.tm_hour = (long) hms % 100; + + tm.tm_year = dmy % 100 + 100; + dmy = dmy / 100; + tm.tm_mon = dmy % 100 - 1; + dmy = dmy / 100; + tm.tm_mday = dmy; + + waypt = waypt_new(); + + WAYPT_SET(waypt, speed, KNOTS_TO_MPS(speed)); + + WAYPT_SET(waypt, course, course); + + nmea_set_waypoint_time(waypt, &tm, microseconds); + + if (latdir == 'S') latdeg = -latdeg; + waypt->latitude = ddmm2degrees(latdeg); + + if (lngdir == 'W') lngdeg = -lngdeg; + waypt->longitude = ddmm2degrees(lngdeg); + + return waypt; +} + +/* + TODO: this function should rather call code from + nmea.c instead of using a local copy of + gprmc_parse + + andreas.grimme@gmx.net +*/ +static waypoint * +itracku_rt_position(posn_status *posn_status) +{ + char line[1024]; + waypoint* wpt; + while (1) + { + gbser_read_line(fd, line, sizeof(line), 5000, 13, 10); + dbg(1, line); + wpt = gprmc_parse(line); + if (wpt) + { + return wpt; + } + } +} + +static void +itracku_rt_deinit(void) +{ + itracku_rd_deinit(); +} + +/**************************************************************************/ + +// capabilities below means: we can only read and write waypoints +// please change this depending on your new module + +ff_vecs_t itracku_vecs = { + ff_type_file, + { + ff_cap_read /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_none /* routes */ + }, + itracku_rd_ser_init, + NULL, + itracku_rd_deinit, + NULL, + itracku_read, + itracku_write, + itracku_exit, + itracku_args, + CET_CHARSET_ASCII, 0, /* ascii is the expected character set */ + /* not fixed, can be changed through command line parameter */ + { itracku_rt_init, itracku_rt_position, itracku_rt_deinit, NULL, NULL, NULL } +}; + +ff_vecs_t itracku_fvecs = { + ff_type_file, + { + ff_cap_read | ff_cap_write /* waypoints */, + ff_cap_read | ff_cap_write /* tracks */, + ff_cap_none /* routes */ + }, + itracku_rd_init, + itracku_wr_init, + itracku_rd_deinit, + itracku_wr_deinit, + itracku_read, + itracku_write, + itracku_exit, + itracku_args, + CET_CHARSET_ASCII, 0, /* ascii is the expected character set */ + /* not fixed, can be changed through command line parameter */ + { NULL, NULL, NULL, NULL, NULL, NULL } +}; + + +/**************************************************************************/ diff --git a/reference/itracku.dat b/reference/itracku.dat new file mode 100644 index 0000000000000000000000000000000000000000..ae3609dfaa9b30d8b992a971703085da6e2d2010 GIT binary patch literal 9568 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 1.210 # # Memory-Map Navigator overlay files (.mmo) diff --git a/vecs.c b/vecs.c index 0e0863cec..9f9ae3311 100644 --- a/vecs.c +++ b/vecs.c @@ -150,6 +150,8 @@ extern ff_vecs_t ggv_ovl_vecs; #if CSVFMTS_ENABLED extern ff_vecs_t jtr_vecs; #endif +extern ff_vecs_t itracku_vecs; +extern ff_vecs_t itracku_fvecs; extern ff_vecs_t sbp_vecs; extern ff_vecs_t mmo_vecs; extern ff_vecs_t skyforce_vecs; @@ -858,6 +860,19 @@ vecs_t vec_list[] = { "jtr" }, #endif + { + &itracku_vecs, + "itracku", + "XAiOX iTrackU Logger", + NULL + }, + + { + &itracku_fvecs, + "itracku-bin", + "XAiOX iTrackU Logger Binary File Format", + "bin" + }, { &sbp_vecs, "sbp", diff --git a/xmldoc/formats/itracku-bin.xml b/xmldoc/formats/itracku-bin.xml new file mode 100644 index 000000000..084c5b6e5 --- /dev/null +++ b/xmldoc/formats/itracku-bin.xml @@ -0,0 +1,5 @@ +Reads the binary format of the XAiOX iTrackU BLUETOOTH GPS-RECEIVER SiRF III data logger. + + Command showing reading an itracku data file. + gpsbabel -i itracku-bin -f itracku.bin -o gpx -F out.gpx + diff --git a/xmldoc/formats/itracku.xml b/xmldoc/formats/itracku.xml new file mode 100644 index 000000000..7093b5da3 --- /dev/null +++ b/xmldoc/formats/itracku.xml @@ -0,0 +1,10 @@ +Serial download protocol for the XAiOX iTrackU BLUETOOTH GPS-RECEIVER SiRF III data logger. + + Command showing a download from itracku connected to com14. + gpsbabel -i itracku -f com14 -o gpx -F out.gpx + +Use auto: as input filename to let gpsbabel detect the serial port to which the logger is connected. + + Command showing a download from itracku with automatic port detection. + gpsbabel -i itracku -f auto: -o gpx -F out.gpx + diff --git a/xmldoc/formats/options/itracku-backup.xml b/xmldoc/formats/options/itracku-backup.xml new file mode 100644 index 000000000..cf5ab5e0b --- /dev/null +++ b/xmldoc/formats/options/itracku-backup.xml @@ -0,0 +1,10 @@ +Specifies a backup file for the binary logger data. New waypoints from the logger will be appended to an existing +backup file. This allows you to create "endless" binary logger files which, for example, could contain the waypoint data of a whole year. +The backup file can be read with gpsbabel by using the itracku format. + + + Download from the data logger while and append the new binary logger data to a backup file. Read the contents of the backup file. + gpsbabel -i itracku,auto,backup=itracku.bak -f dummy -o gpx -F out.gpx + gpsbabel -i itracku -f itracku.bak -o gpx -F out.gpx + + diff --git a/xmldoc/formats/options/itracku-new.xml b/xmldoc/formats/options/itracku-new.xml new file mode 100644 index 000000000..300b3d8b7 --- /dev/null +++ b/xmldoc/formats/options/itracku-new.xml @@ -0,0 +1,12 @@ +Will only pass waypoints along to filters and output formats that are not new, i.e. that are not already stored in the +backup file. This option can only be used with the backup option. +Using this option allows you to output the waypoints of your latest trip with gpsbabel while keeping an endless log of all waypoints +in the backup file. + + + Download from the data logger and append the new logger data to a backup file. Output only the new + waypoints. + gpsbabel -i itracku,auto,backup=itracku.bak,new -f dummy -o gpx -F out.gpx + + + -- 2.30.2